package com.xianniu.ltc.aspect;

import cn.devezhao.bizz.security.member.NoMemberFoundException;
import cn.devezhao.persist4j.engine.ID;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rebuild.core.Application;
import com.rebuild.core.UserContextHolder;
import com.rebuild.core.privileges.bizz.User;
import com.rebuild.core.service.approval.*;
import com.xianniu.ltc.mapper.RobotApprovalStepMapper;
import com.xianniu.ltc.mapper.TUserMapper;
import com.xianniu.ltc.model.entity.RobotApprovalStepDTO;
import com.xianniu.ltc.model.entity.TUserDTO;
import com.xianniu.ltc.model.po.TUserPo;
import com.xxl.sso.core.entity.ReturnT;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 员工异动
 * @Author: dingyx
 * @Date: 2022/1/13 11:44 上午
 */
@Slf4j
@Aspect
@Component
public class UserModifyAspect {
    @Resource
    private TUserMapper tUserMapper;
    @Resource
    private RobotApprovalStepMapper robotApprovalStepMapper;

    @Pointcut("execution(public * com.xianniu.ltc.service.impl.ExternalServiceImpl.addOrUpdateUserForAuth(..))")
    public void userModify(){}


    @Before("userModify()")
    public void around(JoinPoint joinPoint) throws Throwable {
        log.info("用户修改后出发修改相关的切面--------->UserModifyAspect开始");
        Object[] args = joinPoint.getArgs();
        try{
            TUserPo po = JSONObject.parseObject(JSONObject.toJSONString(args[0]), TUserPo.class);
            UserContextHolder.setTenant(po.getSaasCode());
            QueryWrapper<TUserDTO> wrapper = new QueryWrapper<>();
            wrapper.in("login_name", po.getLoginName());
            wrapper.eq("tenant_code", po.getSaasCode());
            List<TUserDTO> userList = tUserMapper.selectList(wrapper);
            if(CollectionUtil.isEmpty(userList)){
                log.info("用户列表为空，无需处理------>结束");
                return;
            }
            log.info("需要修改的用户信息:{}", JSONArray.toJSONString(userList));
            // 如果当前用户被禁用
            if("T".equalsIgnoreCase(po.getIsDisabled())){
                log.info("禁用用户前需要进行的操作-----> 开始");
                // 查询需要用户审批且尚未审批的数据
                QueryWrapper<RobotApprovalStepDTO> approvalWrapper = new QueryWrapper<>();
                approvalWrapper.in("approver", userList.stream().map(TUserDTO::getUserId).collect(Collectors.toList()));
                approvalWrapper.eq("tenant_code", po.getSaasCode());
                approvalWrapper.eq("state", ApprovalState.DRAFT.getState());
                List<RobotApprovalStepDTO> approvalList = robotApprovalStepMapper.selectList(approvalWrapper);
                if(CollectionUtil.isNotEmpty(approvalList)){
                    // 需要变更状态的审批如下：
                    for(RobotApprovalStepDTO approvalStep : approvalList){
                        try {
                            final ID record = ID.valueOf(approvalStep.getRecordId());
                            final ID approver = ID.valueOf(approvalStep.getApprover());
                            try {
                                Application.getUserStore().getUser(approver);
                            }catch (NoMemberFoundException ne){
                                log.info("获取用户{}为空，开始重新初始化{}的数据.", approver, po.getSaasCode());
                                Application.getUserStore().init(po.getSaasCode());
                            }
                            final ApprovalStatus status = ApprovalHelper.getApprovalStatus(record);
                            UserContextHolder.setUser(approver);
                            ApprovalState currentState = status.getCurrentState();
                            if (currentState != ApprovalState.PROCESSING) {
                                log.info("{}当前的状态是:{}，不需要变更审批状态.", record, currentState);
                                continue;
                            }
                            final ID approvalId = ID.valueOf(approvalStep.getApprovalId());
                            ApprovalProcessor processor = new ApprovalProcessor(record, approvalId);

                            List<TUserDTO> approvalUsers;
                            // 如果当前节点没有审批完成并且审批不能缺少A且这个审批人A已离职
                            while (CollectionUtil.isNotEmpty(approvalUsers = needAutoApproval(processor, status, userList, record))) {
                                for(TUserDTO user : approvalUsers){
                                    ID approverId = ID.valueOf(user.getUserId());
                                    // 审批通过
                                    processor.approve(approverId, ApprovalState.APPROVED, "账号不可用，自动跳过", null);
                                }
                            }
                            log.info("审批记录状态变更成功：{}", JSONObject.toJSONString(approvalStep));
                        }catch (Exception e){
                            e.printStackTrace();
                            log.error("审批记录状态变更失败：{}", JSONObject.toJSONString(approvalStep));
                        }finally {
                            UserContextHolder.clearUser();
                        }
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    private List<TUserDTO> needAutoApproval(ApprovalProcessor approvalProcessor, ApprovalStatus status, List<TUserDTO> userList, ID recordId){
        ApprovalState currentState = status.getCurrentState();
        // 如果当前状态不是审核中 不需要处理
        if(!currentState.equals(ApprovalState.PROCESSING)){
            return new ArrayList<>();
        }
        FlowNode currentNode = approvalProcessor.getCurrentNode(UserContextHolder.getTenant());
        FlowNode rootNode = approvalProcessor.getRootNode(UserContextHolder.getTenant());
        // 处理用户，反序列化SELF/DEPART
        Set<ID> idSet = currentNode.getSpecUsers(null, recordId, rootNode);
        List<String> idList = idSet.stream().map(ID::toString).collect(Collectors.toList());
/*
        QueryWrapper<TUserDTO> wrapper = new QueryWrapper<>();
        wrapper.in("user_id", idList);
        wrapper.eq("tenant_code", UserContextHolder.getTenant());
        wrapper.eq("IS_DISABLED", "T");
        List<TUserDTO> userList2 = tUserMapper.selectList(wrapper);
        log.info("需要自动跳过审批的人员名单{}", JSONArray.toJSONString(userList2));
        // befor方法，先手动加到禁用用户列表中
        userList2.addAll(userList);
        if (userList2.size()>0){
            // 或签 且 或签人数大于1的情况下不自动审批通过，跳过即可
            if (currentNode.getSignMode().equalsIgnoreCase(FlowNode.SIGN_OR)
                    && idList.size() > userList2.size()){
                userList = new ArrayList<>();
                return userList;
            }
        }*/
        return userList.stream().filter(user -> idList.contains(user.getUserId())).collect(Collectors.toList());
    }
}
